<?php
/**
 * Created by PhpStorm.
 * User: Akuma
 * Date: 2017/9/14
 * Time: 21:38
 */

namespace App\BCAM\CMTime;


class CMCalendar
{
    protected $monthToUse;

    protected $prepared = false;

    protected $days = array();

    public function __construct($month,$year)
    {
        /*
         * 为要显示的月份建立一个DateTime
         */
        // Y-m| 的| 有和没有是有差别的
        $this->monthToUse = \DateTime::createFromFormat('Y-m|',sprintf("%04d-%02d",$year,$month));

        $this->prepare();
    }

    protected function prepare(){
        // 建立一个数组,包含一个每天的信息
        // 会适当地填充开头和末尾
        // 首先,第一行显示星期几
        collect(['Su','Mo','Tu','We','Th','Fr','Sa'])->map(function($item,$key){
            $endOfRow = ($item == 'Sa');
            //这个$this指代的是 CMCalendar 的对象实例
            $this->days[] = array(
                'type' => 'dow',//类型:标题
                'label' => $item,
                'endOfRow' => $endOfRow
            );
        });

        //接下来,在一周的第一天之前放置占位符
        //w 一周的哪一天,周日为0
        // 亲测:
        // 1.如果精确到月,返回的是1号所在的周位置
        // 2.如果精确到年,返回的是1月1号所在的周位置
        /*$res = \DateTime::createFromFormat('Y|','2017')->format('w');
        dd($res);*/
        //如果是周六 6 ,打印6个空白
        // 以 * 代替 空白
        //Su Mo  Tu We Th Fr Sa
        // *  *  *  *  *  *  1号
        for($i = 0,$j = $this->monthToUse->format('w');$i<$j;$i++){
            $this->days[] = array('type' => 'blank');
        }

        //然后,对于这个月的每一天分别有一项
        $today = date('Y-m-d');
        // t 月天数
        $days = new \DatePeriod($this->monthToUse,new \DateInterval('P1D'),$this->monthToUse->format('t') - 1);
        // $days 第一个元素是 1号
        foreach($days as $day){
            $isToDay = ($day->format('Y-m-d') == $today);
            $endOfRow = ($day->format('w') == 6);
            $this->days[] = array(
                'type' => 'day',//类型:日期
                // j 一个月的哪一天
                'label' => $day->format('j'),//几号
                'today' => $isToDay,//今天的标志
                'endOfRow' => $endOfRow//是否是周六,最后一行的标志位
            );
        }

        //最后,如果endOfWeek不只这个月最后一天,在末尾放置占位符
        if(!$endOfRow){
            for($i = 0,$j = 6 - $day->format('w');$i < $j;$i++){
                $this->days[] = array('type' => 'blank');
            }
        }
    }

    public  function html($opts = array()){
        if(! isset($opts['id'])){
            $opts['id'] = 'calendar';
        }
        if(! isset($opts['month_link'])){
            //$opts['month_link'] = '<a href = "'.htmlentities($_SERVER['PHP_SELF']).'?'.'month=%d&amp;year=%d">%s</a>';
            $opts['month_link'] = '<a href = "'.url('/phpcookbook/time/3-1/getCalendar').'?'.'month=%d&amp;year=%d">%s</a>';
            $classes = array();
            foreach (array('prev','month','next','weekday','blank','day','today') as $class){
                if(isset($opts['class']) && isset($opts['class'][$class])) {
                    $classes[$class] = $opts['class'][$class];
                }else{
                    $classes[$class]  = $class;
                }
            }
        }
        //为上个月建立一个DateTime
        $prevMonth = clone $this->monthToUse;
        $prevMonth->modify('-1 month');
        $prevMonthLink = sprintf($opts['month_link'],$prevMonth->format('m'),$prevMonth->format('Y'),'&laquo');
        //为下个月建立一个DateTime
        $nextMonth = clone $this->monthToUse;
        $nextMonth->modify('+1 month');
        $nextMonthLink = sprintf($opts['month_link'],$nextMonth->format('m'),$nextMonth->format('Y'),'&raquo');
        $html = '<table id="'.htmlentities($opts['id']). '"><tr><td class = "'.htmlentities($classes['prev']).'">'.$prevMonthLink.'</td><td class = "'.htmlentities($classes['month']).'" colspan = "5">'.$this->monthToUse->format('F Y').'</td><td class = "'.htmlentities($classes['next']).'" colspan = "5">'.$nextMonthLink.'</td></tr>';
        $html .= '<tr>';
        $lastDayIndex = count($this->days)-1;
        foreach($this->days as $i=>$day){
            switch ($day['type']){
                case 'dow':
                    $class = 'weekday';
                    $label = htmlentities($day['label']);
                    break;
                case 'blank':
                    $class = 'blank';
                    $label = '&nbsp';
                    break;
                case 'day':
                    $class = $day['today'] ? 'today':'day';
                    $label = htmlentities($day['label']);
                    break;
            }
            $html .= '<td class = "'.htmlentities($classes[$class]).'">'.$label.'</td>';
            if(isset($day['endOfRow']) && $day['endOfRow']){
                $html .= "</tr>\n";
                if($i != $lastDayIndex){
                    $html .= '</tr>';
                }
            }

        }
        $html .= '</table>';
        return $html;
    }
}